home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Express Pd: GALORE
/
Express Pd Galore - The Amiga PD & Shareware CD (1994)(Express Pd)[!][Amiga-CD32-CDTV].iso
/
productivity
/
term
/
termxpr.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-16
|
57KB
|
2,527 lines
/*
** termXPR.c
**
** External transfer protocol support routines
**
** Copyright © 1990-1993 by Olaf `Olsen' Barthel & MXM
** All Rights Reserved
*/
#include "termGlobal.h"
/* How many options xpr_options() will display in a single column. */
#define OPTION_WRAP 16
/* These variables keep the transferred bytes and transfer
* time in seconds.
*/
STATIC LONG ByteVal,
ByteMax,
TimeVal,
TimeMax,
LastTimeDif,
LastPercent;
/* Transfer statistics. */
STATIC ULONG CPS_Minimum,
CPS_Maximum,
CPS_Average,
CPS_Current,
CPS_Count,
CPS_Last;
LONG CPL_Min,
CPL_Avg,
CPL_Cur;
/* The name of the file being transmitted, in case the
* `override transfer path' feature is enabled.
*/
STATIC struct Buffer *CurrentFile;
/* Yet another flag, this one determines whether we already told
* the user that the file we are currently processing will fit
* on the destination device.
*/
STATIC BYTE Alerted,
CarrierMessage;
/* OpenTransferWindow():
*
* Local routine to open the transfer window.
*/
STATIC BYTE
OpenTransferWindow(VOID)
{
/* Block window input. */
BlockWindows();
/* Try to open the transfer window panel. */
if(TransferPanel(LocaleString(MSG_TERMXPR_RECEIVE_FILES_TXT)))
{
/* Supply the log text. */
LogAction(LocaleString(MSG_TERMXPR_LOGMSG_INITIATE_BINARY_DOWNLOAD_TXT));
/* Return success. */
return(TRUE);
}
else
{
/* Re-enable window input. */
ReleaseWindows();
/* Return failure. */
return(FALSE);
}
}
/* NewFileName(STRPTR Source,STRPTR Buffer):
*
* Build a valid file and path name, including path
* substitution, etc.
*/
STATIC STRPTR __regargs
NewFileName(STRPTR Source,STRPTR Buffer)
{
if(Config -> MiscConfig -> OverridePath && !Uploading)
{
if(DownloadPath)
strcpy(Buffer,DownloadPath);
else
strcpy(Buffer,Config -> PathConfig -> BinaryDownloadPath);
if(!Buffer[0])
{
if(!GetCurrentDirName(Buffer,MAX_FILENAME_LENGTH))
Buffer[0] = 0;
}
if(Buffer[0])
{
if(AddPart(Buffer,FilePart(Source),MAX_FILENAME_LENGTH))
return(Buffer);
}
}
else
{
if(FilePart(Source) == Source)
{
if(GetCurrentDirName(Buffer,MAX_FILENAME_LENGTH))
{
if(AddPart(Buffer,Source,MAX_FILENAME_LENGTH))
return(Buffer);
}
}
}
return(Source);
}
/* IdentifySource(STRPTR Name,STRPTR BBSName,struct DateStamp *OpenDate):
*
* Attach source information (BBS name, date and time) to a file.
*/
STATIC VOID __inline
IdentifySource(STRPTR Name,STRPTR BBSName,struct DateStamp *OpenDate)
{
UBYTE SharedBuffer[MAX_FILENAME_LENGTH],
Time[20],
Date[20];
struct DateTime DateTime;
memcpy(&DateTime . dat_Stamp,OpenDate,sizeof(struct DateStamp));
/* Prepare for date conversion. */
DateTime . dat_Format = FORMAT_DOS;
DateTime . dat_Flags = 0;
DateTime . dat_StrDay = NULL;
DateTime . dat_StrDate = Date;
DateTime . dat_StrTime = Time;
/* Convert the date. */
if(DateToStr(&DateTime))
{
if(BBSName[0])
SPrintf(SharedBuffer,"%s %s %s",BBSName,Date,Time);
else
SPrintf(SharedBuffer,"%s %s",Date,Time);
SetComment(Name,SharedBuffer);
}
}
/* GetSeconds(STRPTR String):
*
* Tries to turn a string of the format hh:mm:ss into
* an integer number.
*/
STATIC LONG __inline
GetSeconds(STRPTR String)
{
UBYTE Buffer[20];
LONG Seconds = 0;
memset(Buffer,0,20);
strcpy(Buffer,String);
Seconds += Atol(&Buffer[6]);
Buffer[5] = 0;
Seconds += Atol(&Buffer[3]) * 60;
Buffer[2] = 0;
Seconds += Atol(&Buffer[0]) * 3600;
return(Seconds);
}
/* TruncateName(STRPTR FileName):
*
* Truncates a file name to a maximum of 48 characters.
*/
STATIC STRPTR __inline
TruncateName(STRPTR FileName)
{
WORD Len = strlen(FileName);
if(Len > 48)
{
WORD i;
for(i = Len - 48 ; i < Len ; i++)
{
if(i >= Len - 44 && FileName[i] == '/')
{
STATIC UBYTE NameBuffer[MAX_FILENAME_LENGTH];
strcpy(NameBuffer,".../");
strcat(NameBuffer,&FileName[i + 1]);
return(NameBuffer);
}
}
}
return(FileName);
}
/* CalculateBlocks(LONG Size,LONG BlockSize):
*
* Calculate the number of blocks a file will
* occupy if saved to a disk.
*/
STATIC LONG __inline
CalculateBlocks(LONG Size,LONG BlockSize)
{
LONG Blocks = 1; /* One for the file header. */
BYTE HasExtension = FALSE, /* No extension block yet. */
Extension = 0; /* How many block pointers yet. */
/* Round to next block. */
Size = ((Size + BlockSize - 1) / BlockSize) * BlockSize;
while(Size)
{
/* Add another block. */
Blocks++;
/* Subtract another block. */
Size -= BlockSize;
/* Add another block pointer, if 72 have been
* added, add another extension block.
*/
if((Extension++) == 72)
{
/* If no extension block has been generated
* yet, we were running on the block pointers
* of the file header itself.
*/
if(!HasExtension)
HasExtension = TRUE;
else
Blocks++;
/* Reset extension block counter. */
Extension = 0;
}
}
return(Blocks);
}
/* GetOptionMode(struct xpr_option *Option):
*
* Turn text into a boolean value.
*/
STATIC BYTE __inline
GetOptionMode(struct xpr_option *Option)
{
if(Option)
{
STATIC STRPTR TrueOptions[] =
{
"ON",
"TRUE",
"T",
"YES",
"Y",
NULL
};
register WORD i;
for(i = 0 ; TrueOptions[i] ; i++)
{
if(!Stricmp(Option -> xpro_value,TrueOptions[i]))
return(TRUE);
}
}
return(FALSE);
}
/* CreateAllOptionGadgets():
*
* Create all the gadgets for the xpr options control panel.
*/
STATIC struct Gadget *
CreateAllOptionGadgets(LONG *Count,LONG NumOpts,struct xpr_option *Opts[],struct Gadget *GadgetArray[],struct Gadget **GadgetList,APTR VisualInfo)
{
struct Gadget *Gadget;
struct NewGadget NewGadget;
LONG i,MaxLength = 0,MaxLength1 = 0,MaxWidth,MaxWidth1,Len,NumOptsSmall;
BYTE WrapIt = FALSE;
SZ_SizeSetup(Window -> WScreen,&UserFont,TRUE);
memset(&NewGadget,0,sizeof(struct NewGadget));
*Count = 0;
SZ_ResetMaxWidth();
if(Gadget = CreateContext(GadgetList))
{
NewGadget . ng_TextAttr = &UserFont;
NewGadget . ng_VisualInfo = VisualInfo;
NewGadget . ng_Flags = NG_HIGHLABEL;
/* Precalculate gadget left edge offset. */
if((NumOptsSmall = NumOpts) > OPTION_WRAP)
NumOptsSmall = OPTION_WRAP;
for(i = 0 ; i < NumOptsSmall ; i++)
{
if(Opts[i])
{
switch(Opts[i] -> xpro_type)
{
case XPRO_BOOLEAN:
if((Len = SZ_TextWidth(Opts[i] -> xpro_description)) > MaxLength)
MaxLength = Len;
SZ_UpdateMaxWidth(CHECKBOX_KIND,NULL,0,NULL);
break;
case XPRO_HEADER:
if((Len = SZ_TextWidth(Opts[i] -> xpro_description)) > MaxLength)
MaxLength = Len;
break;
case XPRO_LONG:
case XPRO_STRING:
case XPRO_COMMPAR:
if((Len = SZ_TextWidth(Opts[i] -> xpro_description)) > MaxLength)
MaxLength = Len;
SZ_UpdateMaxWidth(STRING_KIND,NULL,20,NULL);
break;
case XPRO_COMMAND:
SZ_UpdateMaxWidth(TEXT_KIND,Opts[i] -> xpro_description,0,NULL);
break;
default:
break;
}
}
}
MaxWidth = SZ_ResetMaxWidth();
SZ_AddLeftOffset(MaxLength + INTERWIDTH);
for(i = OPTION_WRAP ; i < NumOpts ; i++)
{
if(Opts[i])
{
switch(Opts[i] -> xpro_type)
{
case XPRO_BOOLEAN:
if((Len = SZ_TextWidth(Opts[i] -> xpro_description)) > MaxLength1)
MaxLength1 = Len;
SZ_UpdateMaxWidth(CHECKBOX_KIND,NULL,0,NULL);
break;
case XPRO_HEADER:
if((Len = SZ_TextWidth(Opts[i] -> xpro_description)) > MaxLength1)
MaxLength1 = Len;
break;
case XPRO_LONG:
case XPRO_STRING:
case XPRO_COMMPAR:
if((Len = SZ_TextWidth(Opts[i] -> xpro_description)) > MaxLength1)
MaxLength1 = Len;
SZ_UpdateMaxWidth(STRING_KIND,NULL,20,NULL);
break;
case XPRO_COMMAND:
SZ_UpdateMaxWidth(TEXT_KIND,Opts[i] -> xpro_description,0,NULL);
break;
default:
break;
}
}
}
MaxWidth1 = SZ_ResetMaxWidth();
SZ_SetWidth(MaxWidth);
for(i = 0 ; i < NumOpts ; i++)
{
if(i == OPTION_WRAP + 1)
WrapIt = TRUE;
if(!Opts[i])
continue;
if(WrapIt)
{
SZ_SetWidth(MaxWidth1);
SZ_AddLeftOffset(MaxLength1 + INTERWIDTH);
}
switch(Opts[i] -> xpro_type)
{
case XPRO_BOOLEAN:
NewGadget . ng_GadgetText = Opts[i] -> xpro_description;
NewGadget . ng_GadgetID = i;
GadgetArray[i] = Gadget = CreateGadget(CHECKBOX_KIND,Gadget,&NewGadget,
SZ_Adjust, TRUE,
SZ_AutoWidth, TRUE,
SZ_NewColumn, WrapIt,
GTCB_Checked, GetOptionMode(Opts[i]),
TAG_DONE);
break;
case XPRO_LONG:
NewGadget . ng_GadgetText = Opts[i] -> xpro_description;
NewGadget . ng_GadgetID = i;
GadgetArray[i] = Gadget = CreateGadget(INTEGER_KIND,Gadget,&NewGadget,
SZ_Adjust, TRUE,
SZ_AutoWidth, TRUE,
SZ_NewColumn, WrapIt,
GTIN_Number, Atol(Opts[i] -> xpro_value),
GTST_EditHook, &CommandHook,
TAG_DONE);
break;
case XPRO_STRING:
case XPRO_COMMPAR:
NewGadget . ng_GadgetText = Opts[i] -> xpro_description;
NewGadget . ng_GadgetID = i;
GadgetArray[i] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
SZ_Adjust, TRUE,
SZ_AutoWidth, TRUE,
SZ_NewColumn, WrapIt,
GTST_String, Opts[i] -> xpro_value,
GTST_MaxChars, Opts[i] -> xpro_length - 1,
GTST_EditHook, &CommandHook,
TAG_DONE);
break;
case XPRO_HEADER:
NewGadget . ng_GadgetText = Opts[i] -> xpro_description;
NewGadget . ng_GadgetID = i;
NewGadget . ng_Flags = NG_HIGHLABEL;
GadgetArray[i] = Gadget = CreateGadget(TEXT_KIND,Gadget,&NewGadget,
SZ_Adjust, TRUE,
SZ_AutoWidth, TRUE,
GTTX_Text, " ",
TAG_DONE);
NewGadget . ng_Flags = 0;
break;
case XPRO_COMMAND:
NewGadget . ng_GadgetText = Opts[i] -> xpro_description;
NewGadget . ng_GadgetID = i;
GadgetArray[i] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
SZ_Adjust, TRUE,
SZ_AutoWidth, TRUE,
TAG_DONE);
break;
default:break;
}
WrapIt = FALSE;
}
SZ_ResetMaxWidth();
SZ_UpdateMaxWidth(BUTTON_KIND,LocaleString(MSG_GLOBAL_SAVE_GAD),0,NULL);
SZ_UpdateMaxWidth(BUTTON_KIND,LocaleString(MSG_GLOBAL_CANCEL_GAD),0,NULL);
SZ_SetWidth(SZ_ResetMaxWidth());
NewGadget . ng_GadgetText = LocaleString(MSG_GLOBAL_SAVE_GAD);
NewGadget . ng_GadgetID = GAD_XPROPTIONS_USE;
GadgetArray[i++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
SZ_AlignExtra, TRUE,
SZ_Adjust, TRUE,
SZ_AutoWidth, TRUE,
SZ_AlignLeft, TRUE,
SZ_AlignBottom, TRUE,
GT_Underscore, '_',
TAG_DONE);
NewGadget . ng_GadgetText = LocaleString(MSG_GLOBAL_CANCEL_GAD);
NewGadget . ng_GadgetID = GAD_XPROPTIONS_CANCEL;
GadgetArray[i++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
SZ_Adjust, TRUE,
SZ_AutoWidth, TRUE,
SZ_AlignRight, TRUE,
GT_Underscore, '_',
TAG_DONE);
if(Gadget)
*Count = i;
}
return(Gadget);
}
/* SerialErrorReport(struct IOExtSer *Request):
*
* Report a certain I/O error cause.
*/
STATIC BYTE __regargs
SerialErrorReport(struct IOExtSer *Request)
{
STRPTR ErrorMessage;
BYTE IsFatal;
switch(Request -> IOSer . io_Error)
{
case SerErr_LineErr:
ErrorMessage = LocaleString(MSG_TERMXPR_ERROR_HARDWARE_DATA_OVERRUN_TXT);
IsFatal = FALSE;
break;
case SerErr_ParityErr:
ErrorMessage = LocaleString(MSG_TERMXPR_ERROR_PARITY_ERROR_TXT);
IsFatal = TRUE;
break;
case SerErr_TimerErr:
ErrorMessage = LocaleString(MSG_TERMXPR_ERROR_TIMER_ERROR_TXT);
IsFatal = FALSE;
break;
case SerErr_BufOverflow:
ErrorMessage = LocaleString(MSG_TERMXPR_ERROR_READ_BUFFER_OVERFLOWED_TXT);
IsFatal = FALSE;
break;
case SerErr_NoDSR:
ErrorMessage = LocaleString(MSG_TERMXPR_ERROR_NO_DSR_TXT);
IsFatal = TRUE;
break;
case SerErr_DetectedBreak:
ErrorMessage = LocaleString(MSG_TERMXPR_ERROR_BREAK_DETECTED_TXT);
IsFatal = TRUE;
break;
default:
ErrorMessage = LocaleString(MSG_TERMXPR_ERROR_UNKNOWN_CAUSE_TXT);
IsFatal = FALSE;
break;
}
AddTransferInfo(LocaleString(MSG_TERMXPR_ERROR_TEMPLATE_TXT),Request -> IOSer . io_Error,ErrorMessage);
if(IsFatal)
{
TransferError = TRUE;
return(TRUE);
}
else
return(FALSE);
}
/* xpr_fopen(STRPTR FileName,STRPTR AccessMode):
*
* Open a file for random access.
*/
LONG __saveds __asm
xpr_fopen(register __a0 STRPTR FileName,register __a1 STRPTR AccessMode)
{
UBYTE RealName[MAX_FILENAME_LENGTH];
struct Buffer *File;
Alerted = CarrierMessage = FALSE;
/* Reset transfer counters. */
ByteVal = ByteMax = TimeVal = TimeMax = LastTimeDif = 0;
LastPercent = -1;
/* Reset CPS statistics. */
CPS_Minimum = (ULONG)~0;
CPS_Maximum = 0;
CPS_Average = 0;
CPS_Current = 0;
CPS_Count = 0;
CPS_Last = 0;
/* No window available for output? */
if(!TransferWindow)
OpenTransferWindow();
/* Disable the time and data bars in the transfer window. */
if(TransferWindow)
{
GhostStats(TransferGadgetArray[GAD_TRANSFER_PERCENT]);
GhostStats(TransferGadgetArray[GAD_TRANSFER_TIME]);
}
/* Determine the file name. */
FileName = NewFileName(FileName,RealName);
/* Determine file transfer mode... */
if(File = BufferOpen(FileName,AccessMode))
{
switch(AccessMode[0])
{
case 'r':
LogAction(LocaleString(MSG_TERMXPR_LOGMSG_SEND_FILE_TXT),FileName);
break;
case 'w':
LogAction(LocaleString(MSG_TERMXPR_LOGMSG_RECEIVE_FILE_TXT),FileName);
break;
case 'a':
LogAction(LocaleString(MSG_TERMXPR_LOGMSG_UPDATE_FILE_TXT),FileName);
break;
}
CurrentFile = File;
}
DidTransfer = TRUE;
return((LONG)File);
}
/* xpr_fclose(struct Buffer *File):
*
* Close a file opened by xpr_fopen.
*/
LONG __saveds __asm
xpr_fclose(register __a0 struct Buffer *File)
{
UBYTE RealName[MAX_FILENAME_LENGTH];
struct DateStamp OpenDate;
BYTE WriteAccess,
Used;
/* Save some information. */
OpenDate = File -> OpenDate;
WriteAccess = File -> WriteAccess;
Used = File -> Used;
/* Get the name of the file. */
if(!NameFromFH(File -> FileHandle,RealName,MAX_FILENAME_LENGTH))
RealName[0] = 0;
/* Close the file and see what it brings... */
if(BufferClose(File) && RealName[0])
{
/* Did any access take place at all?
* xprzmodem.library for example just
* opens and closes a file in order to
* see if it exists.
*/
if(!Used)
LogAction(LocaleString(MSG_TERMXPR_CLOSE_FILE_TXT),RealName);
else
{
/* Did we receive or send a file? */
if(WriteAccess)
{
LONG Size;
/* Did the file remain empty? */
if(!(Size = GetFileSize(RealName)))
{
AddTransferInfo(LocaleString(MSG_TERMXPR_FILE_REMOVED_TXT),FilePart(RealName));
/* Delete empty file. */
if(DeleteFile(RealName))
LogAction(LocaleString(MSG_TERMXPR_CLOSE_FILE_REMOVED_TXT),RealName);
else
LogAction(LocaleString(MSG_TERMXPR_CLOSE_FILE_TXT),RealName);
}
else
{
struct Node *SomeNode;
if(ByteMax)
{
if(Size >= ByteMax)
AddTransferInfo(LocaleString(MSG_TERMXPR_FILE_RECEIVED_TXT),FilePart(RealName));
else
AddTransferInfo(LocaleString(MSG_TERMXPR_INCOMPLETE_FILE_RECEIVED_TXT),FilePart(RealName));
}
/* Try to identify the file type. */
switch(Config -> MiscConfig -> IdentifyFiles)
{
case IDENTIFY_FILETYPE:
Identify(RealName);
break;
case IDENTIFY_SOURCE:
IdentifySource(RealName,CurrentBBSName,&OpenDate);
break;
}
if(CPS_Minimum == (ULONG)~0)
CPS_Minimum = 0;
if(CPS_Count == 0)
{
CPS_Average = 0;
CPS_Count = 1;
}
LogAction(LocaleString(MSG_TERMXPR_CLOSE_FILE_BYTES_TXT),RealName,Size,CPS_Minimum,CPS_Average / CPS_Count,CPS_Maximum);
if(SomeNode = CreateGenericListNode(0,RealName))
AddGenericListNode(GenericListTable[GLIST_DOWNLOAD],SomeNode,ADD_GLIST_BOTTOM);
}
}
else
{
/* Set the archived bit on files we uploaded? */
if(Config -> MiscConfig -> SetArchivedBit)
{
struct FileInfoBlock *FileInfo;
if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
{
BPTR FileLock;
/* Get a lock on it. */
if(FileLock = Lock(RealName,ACCESS_READ))
{
/* Examine the file. */
if(Examine(FileLock,FileInfo))
{
/* Remove the lock. */
UnLock(FileLock);
/* Set the `archived' bit. */
SetProtection(RealName,FileInfo -> fib_Protection | FIBF_ARCHIVE);
}
else
UnLock(FileLock);
}
FreeDosObject(DOS_FIB,FileInfo);
}
}
AddTransferInfo(LocaleString(MSG_TERMXPR_FILE_SENT_TXT),FilePart(RealName));
LogAction(LocaleString(MSG_TERMXPR_CLOSE_FILE_TXT),RealName);
RemoveUploadListItem(RealName);
}
}
}
CurrentFile = NULL;
return(1);
}
/* xpr_fread(APTR Buffer,LONG Size,LONG Count,struct Buffer *File):
*
* Read a few bytes from a file.
*/
LONG __saveds __asm
xpr_fread(register __a0 APTR Buffer,register __d0 LONG Size,register __d1 LONG Count,register __a1 struct Buffer *File)
{
return(BufferRead(File,Buffer,Size * Count) / Size);
}
/* xpr_fwrite(APTR Buffer,LONG Size,LONG Count,struct Buffer *File):
*
* Write a few bytes to a file.
*/
LONG __saveds __asm
xpr_fwrite(register __a0 APTR Buffer,register __d0 LONG Size,register __d1 LONG Count,register __a1 struct Buffer *File)
{
return(BufferWrite(File,Buffer,Size * Count) / Size);
}
/* xpr_fseek(struct Buffer *File,LONG Offset,LONG Origin):
*
* Move the read/write pointer in a file.
*/
LONG __saveds __asm
xpr_fseek(register __a0 struct Buffer *File,register __d0 LONG Offset,register __d1 LONG Origin)
{
return(BufferSeek(File,Offset,Origin) ? 0 : -1);
}
/* xpr_sread(APTR Buffer,LONG Size,LONG Timeout):
*
* Read a few bytes from the serial port (including
* timeouts).
*/
LONG __saveds __asm
xpr_sread(register __a0 APTR Buffer,register __d0 LONG Size,register __d1 ULONG Timeout)
{
/* No window available for output? */
if(!TransferWindow)
{
if(!OpenTransferWindow())
return(-1);
}
/* Are both IORequests available? */
if(WriteRequest && ReadRequest)
{
/* Valid size parameter? */
if(Size > 0)
{
/* How many bytes are still in the serial buffer? */
WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
DoIO(WriteRequest);
/* Return error if carrier is lost. */
if(Config -> SerialConfig -> CheckCarrier)
{
if(WriteRequest -> io_Status & CIAF_COMCD)
{
if(!CarrierMessage)
{
CarrierMessage = TRUE;
AddTransferInfo(LocaleString(MSG_TERMXPR_CARRIER_LOST_TXT));
}
Online = FALSE;
TransferError = TRUE;
return(-1);
}
}
/* ALWAYS */
{
register ULONG Waiting;
if(Waiting = WriteRequest -> IOSer . io_Actual)
{
/* No timeout specified? Read as many
* bytes as available.
*/
if(!Timeout)
{
if(Waiting > Size)
Waiting = Size;
ReadRequest -> IOSer . io_Command = CMD_READ;
ReadRequest -> IOSer . io_Data = Buffer;
ReadRequest -> IOSer . io_Length = Waiting;
if(DoIO(ReadRequest))
{
if(SerialErrorReport(ReadRequest))
return(-1);
else
Waiting = ReadRequest -> IOSer . io_Actual;
}
BytesIn += Waiting;
return((LONG)Waiting);
}
/* Enough data pending to be read? */
if(Waiting >= Size)
{
ReadRequest -> IOSer . io_Command = CMD_READ;
ReadRequest -> IOSer . io_Data = Buffer;
ReadRequest -> IOSer . io_Length = Size;
if(DoIO(ReadRequest))
{
if(SerialErrorReport(ReadRequest))
return(-1);
else
Size = ReadRequest -> IOSer . io_Actual;
}
BytesIn += Size;
return(Size);
}
}
else
{
/* No timeout & no bytes available:
* return immediately.
*/
if(!Timeout)
return(0);
}
}
/* ALWAYS */
{
register ULONG SignalSet,WindowMask = PORTMASK(TransferWindow -> UserPort);
/* Set up the timer. */
TimeRequest -> tr_node . io_Command = TR_ADDREQUEST;
TimeRequest -> tr_time . tv_secs = Timeout / MILLION;
TimeRequest -> tr_time . tv_micro = Timeout % MILLION;
/* Set up the read request. */
ReadRequest -> IOSer . io_Command = CMD_READ;
ReadRequest -> IOSer . io_Data = Buffer;
ReadRequest -> IOSer . io_Length = Size;
/* Prevent early termination. */
ClrSignal(SIG_SERIAL | SIG_TIMER);
/* Start IO... */
SendIO(ReadRequest);
SendIO(TimeRequest);
FOREVER
{
SignalSet = Wait(SIG_SERIAL | SIG_TIMER | WindowMask);
/* Abort file transfer? */
if(SignalSet & WindowMask)
{
if(xpr_chkabort() == -1)
{
if(!CheckIO(ReadRequest))
AbortIO(ReadRequest);
if(!CheckIO(TimeRequest))
AbortIO(TimeRequest);
WaitIO(ReadRequest);
WaitIO(TimeRequest);
SendAbort = TRUE;
return(-1);
}
}
/* Receive buffer filled? */
if(SignalSet & SIG_SERIAL)
{
/* Abort the timer request. */
if(!CheckIO(TimeRequest))
AbortIO(TimeRequest);
WaitIO(TimeRequest);
/* Did the request terminate gracefully? */
if(WaitIO(ReadRequest))
{
if(SerialErrorReport(ReadRequest))
return(-1);
else
Size = ReadRequest -> IOSer . io_Actual;
}
BytesIn += Size;
return(Size);
}
/* Hit by timeout? */
if(SignalSet & SIG_TIMER)
{
/* Abort the read request. */
if(!CheckIO(ReadRequest))
AbortIO(ReadRequest);
WaitIO(ReadRequest);
/* Remove the timer request. */
WaitIO(TimeRequest);
/* Did the driver receive any
* data?
*/
if(ReadRequest -> IOSer . io_Actual)
{
BytesIn += ReadRequest -> IOSer . io_Actual;
return((LONG)ReadRequest -> IOSer . io_Actual);
}
else
{
/* Take a second look and query the number of
* bytes ready to be received, there may
* still be some bytes in the buffer.
* Note: this depends on the way the
* driver handles read abort.
*/
WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
DoIO(WriteRequest);
/* Don't read too much. */
if(Size > WriteRequest -> IOSer . io_Actual)
Size = WriteRequest -> IOSer . io_Actual;
/* Are there any bytes to be transferred? */
if(Size)
{
/* Read the data. */
ReadRequest -> IOSer . io_Command = CMD_READ;
ReadRequest -> IOSer . io_Data = Buffer;
ReadRequest -> IOSer . io_Length = Size;
/* Read the data. */
if(DoIO(ReadRequest))
{
if(SerialErrorReport(ReadRequest))
return(-1);
else
Size = ReadRequest -> IOSer . io_Actual;
}
BytesIn += Size;
}
return(Size);
}
}
}
}
}
else
return(0);
}
else
return(-1);
}
/* xpr_swrite(APTR Buffer,LONG Size):
*
* Write a few bytes to the serial port.
*/
LONG __saveds __asm
xpr_swrite(register __a0 APTR Buffer,register __d0 LONG Size)
{
if(WriteRequest)
{
/* Return error if carrier is lost. */
if(Config -> SerialConfig -> CheckCarrier)
{
/* Query the serial status bits. */
WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
DoIO(WriteRequest);
/* Is the carrier signal still present? */
if(WriteRequest -> io_Status & CIAF_COMCD)
{
if(!CarrierMessage)
{
CarrierMessage = TRUE;
AddTransferInfo(LocaleString(MSG_TERMXPR_CARRIER_LOST_TXT));
}
Online = FALSE;
TransferError = TRUE;
return(-1);
}
}
/* Send the data. */
WriteRequest -> IOSer . io_Command = CMD_WRITE;
WriteRequest -> IOSer . io_Data = Buffer;
WriteRequest -> IOSer . io_Length = Size;
if(DoIO(WriteRequest))
{
if(SerialErrorReport(WriteRequest))
return(-1);
}
else
BytesOut += Size;
return(0);
}
else
return(-1);
}
/* xpr_sflush():
*
* Release the contents of all serial buffers.
*/
LONG __saveds __asm
xpr_sflush()
{
if(WriteRequest)
{
WriteRequest -> IOSer . io_Command = CMD_CLEAR;
if(DoIO(WriteRequest))
{
if(SerialErrorReport(WriteRequest))
return(-1);
}
return(0);
}
else
return(-1);
}
/* xpr_update(struct XPR_UPDATE *UpdateInfo):
*
* Update the information displayed in the transfer window.
*/
LONG __saveds __asm
xpr_update(register __a0 struct XPR_UPDATE *UpdateInfo)
{
/* No window available for output? */
if(!TransferWindow)
{
if(!OpenTransferWindow())
return(0);
}
if(UpdateInfo)
{
struct RastPort *RPort = TransferWindow -> RPort;
BYTE NewByte = FALSE,
NewTime = FALSE;
if((UpdateInfo -> xpru_updatemask & XPRU_PROTOCOL) && UpdateInfo -> xpru_protocol)
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_1],0,UpdateInfo -> xpru_protocol);
if((UpdateInfo -> xpru_updatemask & XPRU_MSG) && UpdateInfo -> xpru_msg)
AddTransferInfo(UpdateInfo -> xpru_msg);
if((UpdateInfo -> xpru_updatemask & XPRU_ERRORMSG) && UpdateInfo -> xpru_errormsg)
AddTransferInfo(UpdateInfo -> xpru_errormsg);
if((UpdateInfo -> xpru_updatemask & XPRU_FILENAME) && UpdateInfo -> xpru_filename)
{
UBYTE RealName[MAX_FILENAME_LENGTH];
STRPTR FileName;
FileName = NewFileName(UpdateInfo -> xpru_filename,RealName);
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_2],0,TruncateName(FileName));
if(FileTransferInfo)
{
if(FileTransferInfo -> CurrentFile)
{
struct FileTransferNode *Node = (struct FileTransferNode *)FileTransferInfo -> CurrentFile -> Node . mln_Succ;
if(Node -> Node . mln_Succ)
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_2],1,TruncateName(Node -> Name));
else
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_2],1,LocaleString(MSG_GLOBAL_NONE_TXT));
}
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],2,ConvNumber,FileTransferInfo -> TotalSize);
if(FileTransferInfo -> TotalFiles)
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],4,LocaleString(MSG_TRANSFERPANEL_NUMBER_TO_GO_PERCENT_TXT),FileTransferInfo -> DoneFiles,FileTransferInfo -> TotalFiles,(100 * FileTransferInfo -> DoneFiles) / FileTransferInfo -> TotalFiles);
else
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],4,LocaleString(MSG_TRANSFERPANEL_NUMBER_TO_GO_PERCENT_TXT),FileTransferInfo -> DoneFiles,FileTransferInfo -> TotalFiles,0);
}
}
if((UpdateInfo -> xpru_updatemask & XPRU_FILESIZE) && UpdateInfo -> xpru_filesize != -1)
{
if(CurrentFile)
{
if(CurrentFile -> DirLock)
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],0,ConvNumber10,UpdateInfo -> xpru_filesize);
else
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],0,ConvNumber,UpdateInfo -> xpru_filesize);
}
else
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],0,ConvNumber,UpdateInfo -> xpru_filesize);
if(ByteMax = UpdateInfo -> xpru_filesize)
NewByte = TRUE;
}
if((UpdateInfo -> xpru_updatemask & XPRU_BYTES) && UpdateInfo -> xpru_bytes != -1)
{
if(CurrentFile)
{
if(CurrentFile -> DirLock)
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],1,ConvNumber10,ByteVal = UpdateInfo -> xpru_bytes);
else
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],1,ConvNumber,ByteVal = UpdateInfo -> xpru_bytes);
}
else
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],1,ConvNumber,ByteVal = UpdateInfo -> xpru_bytes);
if(FileTransferInfo)
{
ULONG Len = FileTransferInfo -> DoneSize + UpdateInfo -> xpru_bytes;
if(FileTransferInfo -> TotalSize)
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],3,LocaleString(MSG_TRANSFERPANEL_NUMBER_PERCENT_TXT),Len,(100 * Len) / FileTransferInfo -> TotalSize);
else
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],3,LocaleString(MSG_TRANSFERPANEL_NUMBER_PERCENT_TXT),Len,0);
}
if(ByteMax)
NewByte = TRUE;
if(CurrentFile)
{
if(CurrentFile -> DirLock && !Uploading)
{
if(CurrentFile -> InfoData . id_NumBlocks && CurrentFile -> InfoData . id_BytesPerBlock)
{
if(ByteMax)
{
register LONG Space = CurrentFile -> InfoData . id_NumBlocks - CurrentFile -> InfoData . id_NumBlocksUsed;
if(Space >= 0)
{
register LONG Blocks = CalculateBlocks(ByteMax,CurrentFile -> InfoData . id_BytesPerBlock);
if(Space < Blocks)
{
if(!Alerted)
{
Alerted = TRUE;
Say(LocaleString(MSG_TERMXPR_SAY_FILE_MAY_NOT_FIT_TXT));
}
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_2],2,LocaleString(MSG_TERMXPR_BYTES_FULL_TXT),Space * CurrentFile -> InfoData . id_BytesPerBlock,100 * (CurrentFile -> InfoData . id_NumBlocksUsed) / CurrentFile -> InfoData . id_NumBlocks,LocaleString(MSG_TERMXPR_FILE_MAY_NOT_FIT_TXT));
}
else
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_2],2,LocaleString(MSG_TERMXPR_BYTES_FULL_TXT),Space * CurrentFile -> InfoData . id_BytesPerBlock,100 * (CurrentFile -> InfoData . id_NumBlocksUsed) / CurrentFile -> InfoData . id_NumBlocks,"");
}
else
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_2],2,LocaleString(MSG_TERMXPR_BYTES_FULL_TXT),(CurrentFile -> InfoData . id_NumBlocks - CurrentFile -> InfoData . id_NumBlocksUsed) * CurrentFile -> InfoData . id_BytesPerBlock,100 * (CurrentFile -> InfoData . id_NumBlocksUsed) / CurrentFile -> InfoData . id_NumBlocks);
}
else
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_2],2,LocaleString(MSG_TERMXPR_BYTES_FULL_TXT),(CurrentFile -> InfoData . id_NumBlocks - CurrentFile -> InfoData . id_NumBlocksUsed) * CurrentFile -> InfoData . id_BytesPerBlock,100 * (CurrentFile -> InfoData . id_NumBlocksUsed) / CurrentFile -> InfoData . id_NumBlocks);
}
}
}
}
if((UpdateInfo -> xpru_updatemask & XPRU_BLOCKS) && UpdateInfo -> xpru_blocks != -1)
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],5,ConvNumber,UpdateInfo -> xpru_blocks);
if((UpdateInfo -> xpru_updatemask & XPRU_DATARATE) && UpdateInfo -> xpru_datarate > 0)
{
register LONG Change;
CPS_Current = UpdateInfo -> xpru_datarate;
if(CPS_Last)
{
if(CPS_Last < UpdateInfo -> xpru_datarate)
Change = (100 * (UpdateInfo -> xpru_datarate - CPS_Last)) / CPS_Last;
else
Change = (100 * (CPS_Last - UpdateInfo -> xpru_datarate)) / CPS_Last;
}
else
Change = 100;
if(Change > 1)
{
SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],0,ConvNumber,UpdateInfo -> xpru_datarate);
CPS_Last = UpdateInfo -> xpru_datarate;
}
if(UpdateInfo -> xpru_datarate < CPS_Minimum)
CPS_Minimum = UpdateInfo -> xpru_datarate;
if(UpdateInfo -> xpru_datarate > CPS_Maximum)
CPS_Maximum = UpdateInfo -> xpru_datarate;
if((ULONG)(CPS_Average + UpdateInfo -> xpru_datarate) >= CPS_Average)
{
CPS_Average += UpdateInfo -> xpru_datarate;
CPS_Count++;
}
}
if((UpdateInfo -> xpru_updatemask & XPRU_CHARDELAY) && UpdateInfo -> xpru_chardelay != -1)
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],1,ConvNumber,UpdateInfo -> xpru_chardelay);
if((UpdateInfo -> xpru_updatemask & XPRU_PACKETDELAY) && UpdateInfo -> xpru_packetdelay != -1)
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],2,ConvNumber,UpdateInfo -> xpru_packetdelay);
if((UpdateInfo -> xpru_updatemask & XPRU_PACKETTYPE) && UpdateInfo -> xpru_packettype != -1)
{
if(UpdateInfo -> xpru_packettype > 32 && UpdateInfo -> xpru_packettype < 256)
{
if(IsPrintable[UpdateInfo -> xpru_packettype])
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],3,"`%lc'",UpdateInfo -> xpru_packettype);
else
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],3,ConvNumber,UpdateInfo -> xpru_packettype);
}
else
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],3,ConvNumber,UpdateInfo -> xpru_packettype);
}
if((UpdateInfo -> xpru_updatemask & XPRU_BLOCKCHECK) && UpdateInfo -> xpru_blockcheck)
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],4,UpdateInfo -> xpru_blockcheck);
if((UpdateInfo -> xpru_updatemask & XPRU_BLOCKSIZE) && UpdateInfo -> xpru_blocksize != -1)
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],5,ConvNumber,UpdateInfo -> xpru_blocksize);
if((UpdateInfo -> xpru_updatemask & XPRU_EXPECTTIME) && UpdateInfo -> xpru_expecttime)
{
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT2],0,UpdateInfo -> xpru_expecttime);
if(TimeMax = GetSeconds((STRPTR)UpdateInfo -> xpru_expecttime))
NewTime = TRUE;
}
if((UpdateInfo -> xpru_updatemask & XPRU_ELAPSEDTIME) && UpdateInfo -> xpru_elapsedtime)
{
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT2],1,UpdateInfo -> xpru_elapsedtime);
TimeVal = GetSeconds((STRPTR)UpdateInfo -> xpru_elapsedtime);
if(TimeMax)
NewTime = TRUE;
}
if((UpdateInfo -> xpru_updatemask & XPRU_ERRORS) && UpdateInfo -> xpru_errors != -1)
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_RIGHT2],0,ConvNumber,UpdateInfo -> xpru_errors);
if((UpdateInfo -> xpru_updatemask & XPRU_TIMEOUTS) && UpdateInfo -> xpru_timeouts != -1)
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_RIGHT2],1,ConvNumber,UpdateInfo -> xpru_timeouts);
if(NewByte)
{
LONG Percent;
if(ByteMax)
Percent = (100 * ByteVal) / ByteMax;
else
Percent = 0;
if(Percent != LastPercent)
{
LastPercent = Percent;
ShowStats(TransferGadgetArray[GAD_TRANSFER_PERCENT],ByteVal,ByteMax);
ShowString(TransferGadgetArray[GAD_TRANSFER_PERCENT],"%ld%%",Percent);
}
}
if(NewTime)
{
register LONG TimeDif,Change;
if(TimeVal > TimeMax)
TimeDif = 0;
else
TimeDif = TimeMax - TimeVal;
if(LastTimeDif)
{
if(LastTimeDif < TimeDif)
Change = (100 * (TimeDif - LastTimeDif)) / LastTimeDif;
else
Change = (100 * (LastTimeDif - TimeDif)) / LastTimeDif;
}
else
Change = 100;
/* Don't update the display unless the change
* exceeds 2% of the previous value.
*/
if(Change > 2)
{
UBYTE TimeBuffer[20],
DateBuffer[20];
struct DateTime DateTime;
LastTimeDif = TimeDif;
ShowStats(TransferGadgetArray[GAD_TRANSFER_TIME],TimeDif,TimeMax);
ShowString(TransferGadgetArray[GAD_TRANSFER_TIME],"%2ld:%02ld:%02ld",TimeDif / 3600,(TimeDif / 60) % 60,TimeDif % 60);
/* A rapidly changing transfer time display would
* cause the transfer completion time display to
* change at the same pace. As the completion time
* display calculation is rather costly, a change smaller
* than 5% of the previous value is silently ignored.
*/
if(Change > 5)
{
/* Obtain current time. */
DateStamp(&DateTime . dat_Stamp);
/* Add the time to go. */
DateTime . dat_Stamp . ds_Tick += (TimeDif % 60) * TICKS_PER_SECOND;
DateTime . dat_Stamp . ds_Minute += TimeDif / 60 + DateTime . dat_Stamp . ds_Tick / (60 * TICKS_PER_SECOND);
DateTime . dat_Stamp . ds_Days += DateTime . dat_Stamp . ds_Minute / 1440;
DateTime . dat_Stamp . ds_Tick %= 60 * TICKS_PER_SECOND;
DateTime . dat_Stamp . ds_Minute %= 1440;
/* Convert it to human readable form. */
DateTime . dat_Format = FORMAT_DOS;
DateTime . dat_Flags = DTF_SUBST;
DateTime . dat_StrDay = NULL;
DateTime . dat_StrDate = DateBuffer;
DateTime . dat_StrTime = TimeBuffer;
/* Conversion succeeded? */
if(DateToStr(&DateTime))
SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_2],3,"%s %s",DateBuffer,TimeBuffer);
}
}
}
}
if(TransferPerfWindow)
{
struct RastPort *RPort = TransferPerfWindow -> RPort;
LONG Height,Left,Top,Min,Avg,Cur;
Left = TransferPerfWindow -> Width - (TransferPerfWindow -> BorderRight + 1);
Height = TransferPerfWindow -> Height - (TransferPerfWindow -> BorderTop + TransferPerfWindow -> BorderBottom + 1);
Top = TransferPerfWindow -> BorderTop + Height;
if(CPS_Maximum && CPS_Maximum != ~0)
{
Min = (Height * CPS_Minimum) / CPS_Maximum;
Cur = (Height * CPS_Current) / CPS_Maximum;
if(CPS_Count)
Avg = ((CPS_Average / CPS_Count) * Height) / CPS_Maximum;
else
Avg = 0;
}
else
Min = Avg = Cur = 0;
if(CPL_Min == -1)
CPL_Min = Min;
if(CPL_Avg == -1)
CPL_Avg = Avg;
if(CPL_Cur == -1)
CPL_Cur = Cur;
ScrollRaster(RPort,1,0,TransferPerfWindow -> BorderLeft,TransferPerfWindow -> BorderTop,TransferPerfWindow -> Width - (TransferPerfWindow -> BorderRight + 1),TransferPerfWindow -> Height - (TransferPerfWindow -> BorderBottom + 1));
if(CPL_Cur != -1 && Cur != -1)
{
SetAPen(RPort,DrawInfo -> dri_Pens[SHADOWPEN]);
Move(RPort,Left,Top - CPL_Cur);
Draw(RPort,Left,Top - Cur);
}
if(CPL_Min != -1 && Min != -1)
{
SetAPen(RPort,DrawInfo -> dri_Pens[HIGHLIGHTTEXTPEN]);
Move(RPort,Left,Top - CPL_Min);
Draw(RPort,Left,Top - Min);
}
if(CPL_Avg != -1 && Avg != -1)
{
SetAPen(RPort,DrawInfo -> dri_Pens[FILLPEN]);
Move(RPort,Left,Top - CPL_Avg);
Draw(RPort,Left,Top - Avg);
}
CPL_Min = Min;
CPL_Avg = Avg;
CPL_Cur = Cur;
}
return(1);
}
/* xpr_chkabort():
*
* Check if the user has aborted the transfer.
*/
LONG __saveds __asm
xpr_chkabort()
{
struct IntuiMessage *Massage;
struct Window *IWindow;
ULONG IClass,
Code;
struct Gadget *Gadget;
LONG Result = 0;
/* No window available for output? */
if(!TransferWindow)
{
if(!OpenTransferWindow())
return(-1);
}
/* Are we to check the carrier status? */
if(Config -> SerialConfig -> CheckCarrier)
{
WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
DoIO(WriteRequest);
/* Return error if carrier is lost. */
if(WriteRequest -> io_Status & CIAF_COMCD)
{
if(!CarrierMessage)
{
CarrierMessage = TRUE;
AddTransferInfo(LocaleString(MSG_TERMXPR_CARRIER_LOST_TXT));
}
Online = FALSE;
TransferError = TRUE;
return(-1);
}
}
/* Process all incoming messages. */
while(Massage = (struct IntuiMessage *)GT_GetIMsg(TransferWindow -> UserPort))
{
IClass = Massage -> Class;
Code = Massage -> Code;
Gadget = (struct Gadget *)Massage -> IAddress;
IWindow = Massage -> IDCMPWindow;
GT_ReplyIMsg(Massage);
if(IWindow == TransferWindow)
{
KeySelect(TransferGadgetArray,4,Code,TransferWindow,&Gadget,&IClass,&Code);
if(!Result)
{
if(IClass == IDCMP_NEWSIZE)
{
if(!(TransferWindow -> Flags & WFLG_ZOOMED))
{
LONG TimeDif = (TimeMax - TimeVal) < 0 ? 0 : TimeMax - TimeVal;
RefreshTransferWindow();
ShowStats(TransferGadgetArray[GAD_TRANSFER_PERCENT],ByteVal,ByteMax);
if(ByteMax)
ShowString(TransferGadgetArray[GAD_TRANSFER_PERCENT],"%ld%%",(100 * ByteVal) / ByteMax);
else
ShowString(TransferGadgetArray[GAD_TRANSFER_PERCENT],"%ld%%",0);
ShowStats(TransferGadgetArray[GAD_TRANSFER_TIME],TimeDif,TimeMax);
ShowString(TransferGadgetArray[GAD_TRANSFER_TIME],"%2ld:%02ld:%02ld",TimeDif / 3600,(TimeDif / 60) % 60,TimeDif % 60);
}
}
if(IClass == IDCMP_CLOSEWINDOW)
{
LogAction(LocaleString(MSG_TERMXPR_LOGMSG_TRANSFER_ABORTED_TXT));
TransferAborted = TRUE;
Result = -1;
}
if(IClass == IDCMP_GADGETUP)
{
switch(Gadget -> GadgetID)
{
case GAD_TRANSFER_ABORT:
LogAction(LocaleString(MSG_TERMXPR_LOGMSG_TRANSFER_ABORTED_TXT));
TransferAborted = TRUE;
Result = -1;
break;
case GAD_TRANSFER_SKIP:
LogAction(LocaleString(MSG_TERMXPR_LOGMSG_FILE_SKIPPED_TXT));
Result = 1;
break;
}
}
}
}
else
{
if(TransferPerfWindow)
{
struct RastPort *RPort = TransferPerfWindow -> RPort;
if(IClass == IDCMP_NEWSIZE)
{
SetAPen(RPort,0);
RectFill(RPort,TransferPerfWindow -> BorderLeft,TransferPerfWindow -> BorderTop,TransferPerfWindow -> Width - (TransferPerfWindow -> BorderRight + 1),TransferPerfWindow -> Height - (TransferPerfWindow -> BorderBottom + 1));
CPL_Min = CPL_Avg = CPL_Cur = -1;
}
if(IClass == IDCMP_CLOSEWINDOW)
{
PutWindowInfo(WINDOW_PERF,TransferPerfWindow -> LeftEdge,TransferPerfWindow -> TopEdge,TransferPerfWindow -> Width,TransferPerfWindow -> Height);
CloseWindowSafely(TransferPerfWindow);
TransferPerfWindow = NULL;
}
}
}
}
return(Result);
}
/* CreateAllGetsGadgets():
*
* Create all the gadgets required by xpr_gets() and the like.
*/
struct Gadget *
CreateAllGetsGadgets(BYTE LoadGadget,BYTE Password,WORD MaxChars,STRPTR String,STRPTR Prompt,struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,struct Screen *Screen)
{
struct Gadget *Gadget;
struct NewGadget NewGadget;
if(MaxChars < 1)
MaxChars = 255;
memset(&NewGadget,0,sizeof(struct NewGadget));
SZ_SizeSetup(Screen,&UserFont,TRUE);
if(Gadget = CreateContext(GadgetList))
{
WORD Width = SZ_TextWidth(Prompt),Counter = 0;
if(Width < SZ_Width(STRING_KIND,NULL,60,NULL))
Width = SZ_Width(STRING_KIND,NULL,60,NULL);
SZ_SetWidth(Width);
NewGadget . ng_GadgetText = Prompt;
NewGadget . ng_TextAttr = &UserFont;
NewGadget . ng_VisualInfo = VisualInfo;
NewGadget . ng_GadgetID = Counter;
NewGadget . ng_Flags = PLACETEXT_ABOVE;
if(LoadGadget)
{
GadgetArray[Counter++] = Gadget = CreateGadget(Password ? PASSWORD_KIND : STRING_KIND,Gadget,&NewGadget,
SZ_Adjust, TRUE,
SZ_AutoWidth, TRUE,
SZ_LeaveFolder, TRUE,
GTST_MaxChars, MaxChars,
GTST_String, String,
GA_TabCycle, FALSE,
TAG_DONE);
NewGadget . ng_GadgetID = Counter;
GadgetArray[Counter++] = Gadget = CreateGadget(FILE_KIND,Gadget,&NewGadget,
SZ_Adjust, TRUE,
SZ_AutoWidth, TRUE,
SZ_PlaceLeft, TRUE,
TAG_DONE);
}
else
{
GadgetArray[Counter++] = Gadget = CreateGadget(Password ? PASSWORD_KIND : STRING_KIND,Gadget,&NewGadget,
SZ_Adjust, TRUE,
SZ_AutoWidth, TRUE,
GTST_MaxChars, MaxChars,
GTST_String, String,
GA_TabCycle, FALSE,
TAG_DONE);
GadgetArray[Counter++] = NULL;
}
SZ_UpdateMaxWidth(BUTTON_KIND,LocaleString(MSG_TERMXPR_OKAY_GAD),0,NULL);
SZ_UpdateMaxWidth(BUTTON_KIND,LocaleString(MSG_GLOBAL_CANCEL_GAD),0,NULL);
SZ_SetWidth(SZ_ResetMaxWidth());
NewGadget . ng_GadgetText = LocaleString(MSG_TERMXPR_OKAY_GAD);
NewGadget . ng_GadgetID = Counter;
NewGadget . ng_Flags = 0;
GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
SZ_Adjust, TRUE,
SZ_AutoWidth, TRUE,
SZ_AlignExtra, TRUE,
SZ_AlignLeft, TRUE,
SZ_AlignBottom, TRUE,
GT_Underscore, '_',
TAG_DONE);
NewGadget . ng_GadgetText = LocaleString(MSG_GLOBAL_CANCEL_GAD);
NewGadget . ng_GadgetID = Counter;
GadgetArray[Counter] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
SZ_Adjust, TRUE,
SZ_AutoWidth, TRUE,
SZ_AlignRight, TRUE,
GT_Underscore, '_',
TAG_DONE);
}
return(Gadget);
}
/* xpr_gets(STRPTR Prompt,STRPTR Buffer):
*
* Prompt the user for string input.
*/
LONG __saveds __asm
xpr_gets(register __a0 STRPTR Prompt,register __a1 STRPTR Buffer)
{
struct Gadget *GadgetList = NULL;
struct Gadget *GadgetArray[4];
struct Window *PanelWindow;
LONG Success = FALSE;
if(!Prompt)
Prompt = LocaleString(MSG_TERMXPR_INPUT_REQUIRED_TXT);
if(CreateAllGetsGadgets(FALSE,FALSE,0,Buffer,Prompt,GadgetArray,&GadgetList,VisualInfo,Window -> WScreen))
{
if(PanelWindow = OpenWindowTags(NULL,
WA_Left, GetScreenLeft(Window) + (GetScreenWidth(Window) - SZ_GetWindowWidth()) / 2,
WA_Top, GetScreenTop(Window) + (GetScreenHeight(Window) - SZ_GetWindowHeight()) / 2,
WA_Width, SZ_GetWindowWidth(),
WA_Height, SZ_GetWindowHeight(),
WA_Activate, TRUE,
WA_DragBar, TRUE,
WA_DepthGadget, TRUE,
WA_CloseGadget, TRUE,
WA_RMBTrap, TRUE,
WA_CustomScreen,Window -> WScreen,
WA_IDCMP, IDCMP_GADGETDOWN | IDCMP_ACTIVEWINDOW | IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY | IDCMP_RAWKEY | BUTTONIDCMP | STRINGIDCMP,
WA_Title, LocaleString(MSG_GLOBAL_ENTER_TEXT_TXT),
TAG_DONE))
{
struct IntuiMessage *Massage;
ULONG IClass,Code,Qualifier;
struct Gadget *Gadget;
BYTE Terminated = FALSE;
PushWindow(PanelWindow);
AddGList(PanelWindow,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
RefreshGList(GadgetList,PanelWindow,NULL,(UWORD)-1);
GT_RefreshWindow(PanelWindow,NULL);
ActiveGadget = NULL;
while(!Terminated)
{
WaitPort(PanelWindow -> UserPort);
while(!Terminated && (Massage = (struct IntuiMessage *)GT_GetIMsg(PanelWindow -> UserPort)))
{
IClass = Massage -> Class;
Code = Massage -> Code;
Gadget = (struct Gadget *)Massage -> IAddress;
Qualifier = Massage -> Qualifier;
GT_ReplyIMsg(Massage);
if(IClass == IDCMP_VANILLAKEY)
KeySelect(GadgetArray,3,Code,PanelWindow,&Gadget,&IClass,&Code);
if(IClass == IDCMP_RAWKEY && Code == HELP_CODE)
DisplayBeep(PanelWindow -> WScreen);
if(IClass == IDCMP_GADGETDOWN)
{
if((Gadget -> GadgetType & GTYP_GTYPEMASK) == GTYP_STRGADGET)
ActiveGadget = Gadget;
}
if(IClass == IDCMP_ACTIVEWINDOW && ActiveGadget)
ActivateGadget(ActiveGadget,PanelWindow,NULL);
if(IClass == IDCMP_CLOSEWINDOW)
Terminated = TRUE;
if(IClass == IDCMP_GADGETUP)
{
switch(Gadget -> GadgetID)
{
case 0: if(!(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
{
strcpy(Buffer,SZ_GetString(GadgetArray[0]));
Success = TRUE;
Terminated = TRUE;
}
break;
case 2: strcpy(Buffer,SZ_GetString(GadgetArray[0]));
Success = TRUE;
Terminated = TRUE;
break;
case 3: Terminated = TRUE;
break;
}
}
}
}
ActiveGadget = NULL;
RemoveGList(PanelWindow,GadgetList,(UWORD)-1);
PopWindow();
CloseWindow(PanelWindow);
}
FreeGadgets(GadgetList);
}
return(Success);
}
/* xpr_setserial(LONG Status):
*
* Set/read the serial status (parameters).
*/
LONG __saveds __asm
xpr_setserial(register __d0 LONG Status)
{
if(WriteRequest)
{
STATIC LONG XprBauds[12] =
{
110,
300,
1200,
2400,
4800,
9600,
19200,
31250,
38400,
57600,
76800,
115200
};
LONG Return,i;
WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
DoIO(WriteRequest);
Return = WriteRequest -> io_SerFlags & 0xFF;
if(WriteRequest -> io_ExtFlags & SEXTF_MSPON)
Return |= ST_PARTYMARKON;
if(WriteRequest -> io_ExtFlags & SEXTF_MARK)
Return |= ST_PARTYMARK;
if(WriteRequest -> io_StopBits == 2)
Return |= ST_2BITS;
if(WriteRequest -> io_ReadLen == 7)
Return |= ST_READ7;
if(WriteRequest -> io_WriteLen == 7)
Return |= ST_WRITE7;
for(i = 0 ; i < 12 ; i++)
{
if(XprBauds[i] >= WriteRequest -> io_Baud)
{
Return |= (i << 16);
break;
}
}
/* Update serial parameters, don't change
* the baud rate however.
*/
if(Status != -1)
{
WriteRequest -> io_SerFlags = Status & 0xFF;
WriteRequest -> io_ExtFlags = 0;
if(Status & ST_PARTYMARKON)
WriteRequest -> io_ExtFlags |= SEXTF_MSPON;
if(Status & ST_PARTYMARK)
WriteRequest -> io_ExtFlags |= SEXTF_MARK;
if(Status & ST_2BITS)
WriteRequest -> io_StopBits = 2;
else
WriteRequest -> io_StopBits = 1;
if(Status & ST_READ7)
WriteRequest -> io_ReadLen = 7;
else
WriteRequest -> io_ReadLen = 8;
if(Status & ST_WRITE7)
WriteRequest -> io_WriteLen = 7;
else
WriteRequest -> io_WriteLen = 8;
ReadRequest -> io_Baud = WriteRequest -> io_Baud;
ReadRequest -> io_SerFlags = WriteRequest -> io_SerFlags;
ReadRequest -> io_ExtFlags = WriteRequest -> io_ExtFlags;
ReadRequest -> io_StopBits = WriteRequest -> io_StopBits;
ReadRequest -> io_ReadLen = WriteRequest -> io_ReadLen;
ReadRequest -> io_WriteLen = WriteRequest -> io_WriteLen;
WriteRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
DoIO(WriteRequest);
ReadRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
DoIO(ReadRequest);
GetFlags(Config,WriteRequest);
}
return(Return);
}
else
return(-1);
}
/* xpr_ffirst(STRPTR Buffer,STRPTR Pattern):
*
* Batch file upload: find the first matching file and return
* its name.
*/
LONG __saveds __asm
xpr_ffirst(register __a0 STRPTR Buffer,register __a1 STRPTR Pattern)
{
if(FileTransferInfo)
{
FileTransferInfo -> DoneSize = 0;
FileTransferInfo -> DoneFiles = 0;
FileTransferInfo -> CurrentFile = (struct FileTransferNode *)FileTransferInfo -> FileList . mlh_Head;
FileTransferInfo -> CurrentSize = FileTransferInfo -> CurrentFile -> Size;
strcpy(Buffer,FileTransferInfo -> CurrentFile -> Name);
return(1);
}
else
return(0);
}
/* xpr_fnext(LONG OldState,STRPTR Buffer,STRPTR Pattern):
*
* Batch file upload: find the next matching file
* - if any - and return its name.
*/
LONG __saveds __asm
xpr_fnext(register __d0 LONG OldState,register __a0 STRPTR Buffer,register __a1 STRPTR Pattern)
{
if(FileTransferInfo)
{
if(FileTransferInfo -> CurrentFile -> Node . mln_Succ -> mln_Succ)
{
FileTransferInfo -> DoneSize += FileTransferInfo -> CurrentSize;
FileTransferInfo -> DoneFiles += 1;
FileTransferInfo -> CurrentFile = (struct FileTransferNode *)FileTransferInfo -> CurrentFile -> Node . mln_Succ;
FileTransferInfo -> CurrentSize = FileTransferInfo -> CurrentFile -> Size;
strcpy(Buffer,FileTransferInfo -> CurrentFile -> Name);
return(1);
}
}
return(0);
}
/* xpr_finfo(STRPTR FileName,LONG InfoType):
*
* Return information on a given file.
*/
LONG __saveds __asm
xpr_finfo(register __a0 STRPTR FileName,register __d0 LONG InfoType)
{
struct FileInfoBlock *FileInfo;
LONG Size;
switch(InfoType)
{
/* Return the file size. */
case 1: Size = 0;
if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
{
UBYTE RealName[MAX_FILENAME_LENGTH];
BPTR FileLock;
FileName = NewFileName(FileName,RealName);
if(FileLock = Lock(FileName,ACCESS_READ))
{
if(Examine(FileLock,FileInfo))
{
if(FileInfo -> fib_DirEntryType < 0)
Size = FileInfo -> fib_Size;
}
UnLock(FileLock);
}
FreeDosObject(DOS_FIB,FileInfo);
}
return(Size);
/* Return the file transfer mode. */
case 2: return(BinaryTransfer ? 1 : 2);
/* Ignore the rest. */
default:return(0);
}
}
/* xpr_options(LONG NumOpts,struct xpr_option **Opts):
*
* Provide a more polished user interface to set the
* transfer protocol options.
*/
ULONG __saveds __asm
xpr_options(register __d0 LONG NumOpts,register __a0 struct xpr_option **Opts)
{
struct Gadget *GadgetList = NULL;
struct Gadget *GadgetArray[34];
struct Window *PanelWindow;
LONG i,Count;
ULONG Flags = 0;
/* We only have 32 bits! */
if(NumOpts > 32)
NumOpts = 32;
if(CreateAllOptionGadgets(&Count,NumOpts,Opts,GadgetArray,&GadgetList,VisualInfo))
{
if(PanelWindow = OpenWindowTags(NULL,
WA_Left, GetScreenLeft(Window) + (GetScreenWidth(Window) - SZ_GetWindowWidth()) / 2,
WA_Top, GetScreenTop(Window) + (GetScreenHeight(Window) - SZ_GetWindowHeight()) / 2,
WA_Width, SZ_GetWindowWidth(),
WA_Height, SZ_GetWindowHeight(),
WA_Activate, TRUE,
WA_DragBar, TRUE,
WA_DepthGadget, TRUE,
WA_CloseGadget, TRUE,
WA_RMBTrap, TRUE,
WA_CustomScreen,Window -> WScreen,
WA_IDCMP, IDCMP_GADGETDOWN | IDCMP_ACTIVEWINDOW | IDCMP_CLOSEWINDOW | IDCMP_RAWKEY | IDCMP_VANILLAKEY | CHECKBOXIDCMP | STRINGIDCMP | INTEGERIDCMP | BUTTONIDCMP,
WA_Title, OptionTitle ? OptionTitle : LocaleString(MSG_TERMXPR_TRANSFER_OPTIONS_TXT),
TAG_DONE))
{
struct IntuiMessage *Massage;
ULONG IClass,Code;
struct Gadget *Gadget;
BYTE Terminated = FALSE,
CheckFlags = FALSE;
PushWindow(PanelWindow);
AddGList(PanelWindow,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
RefreshGList(GadgetList,PanelWindow,NULL,(UWORD)-1);
GT_RefreshWindow(PanelWindow,NULL);
ActiveGadget = NULL;
ClrSignal(SIG_BREAK);
while(!Terminated)
{
if(Wait(PORTMASK(PanelWindow -> UserPort) | SIG_BREAK) & SIG_BREAK)
break;
while(!Terminated && (Massage = (struct IntuiMessage *)GT_GetIMsg(PanelWindow -> UserPort)))
{
IClass = Massage -> Class;
Code = Massage -> Code;
Gadget = (struct Gadget *)Massage -> IAddress;
GT_ReplyIMsg(Massage);
if(IClass == IDCMP_VANILLAKEY)
KeySelect(GadgetArray,Count,Code,PanelWindow,&Gadget,&IClass,&Code);
if(IClass == IDCMP_RAWKEY && Code == HELP_CODE)
DisplayBeep(PanelWindow -> WScreen);
if(IClass == IDCMP_GADGETDOWN)
{
if((Gadget -> GadgetType & GTYP_GTYPEMASK) == GTYP_STRGADGET)
ActiveGadget = Gadget;
}
if(IClass == IDCMP_ACTIVEWINDOW && ActiveGadget)
ActivateGadget(ActiveGadget,PanelWindow,NULL);
if(IClass == IDCMP_CLOSEWINDOW)
Terminated = TRUE;
if(IClass == IDCMP_GADGETUP)
{
switch(Gadget -> GadgetID)
{
case GAD_XPROPTIONS_USE:
Terminated = CheckFlags = TRUE;
break;
case GAD_XPROPTIONS_CANCEL:
Terminated = TRUE;
break;
default:
if(Gadget -> GadgetID < NumOpts)
{
if(Opts[Gadget -> GadgetID] -> xpro_type == XPRO_COMMAND)
{
Flags |= (1 << Gadget -> GadgetID);
Terminated = CheckFlags = TRUE;
}
}
break;
}
}
}
}
if(CheckFlags)
{
for(i = 0 ; i < NumOpts ; i++)
{
switch(Opts[i] -> xpro_type)
{
case XPRO_BOOLEAN:
if(SZ_GetChecked(GadgetArray[i]) != GetOptionMode(Opts[i]))
{
Flags |= (1 << i);
if(SZ_GetChecked(GadgetArray[i]))
strcpy(Opts[i] -> xpro_value,"yes");
else
strcpy(Opts[i] -> xpro_value,"no");
NewOptions = TRUE;
}
break;
case XPRO_COMMPAR:
case XPRO_LONG:
case XPRO_STRING:
if(strcmp(Opts[i] -> xpro_value,SZ_GetString(GadgetArray[i])))
{
Flags |= (1 << i);
strcpy(Opts[i] -> xpro_value,SZ_GetString(GadgetArray[i]));
NewOptions = TRUE;
}
break;
}
}
}
else
{
NewOptions = FALSE;
Flags = NULL;
}
ActiveGadget = NULL;
RemoveGList(PanelWindow,GadgetList,(UWORD)-1);
PopWindow();
CloseWindow(PanelWindow);
}
}
FreeGadgets(GadgetList);
return(Flags);
}
/* xpr_unlink(STRPTR FileName):
*
* Remove (delete) a given file.
*/
LONG __saveds __asm
xpr_unlink(register __a0 STRPTR FileName)
{
/* Sorry, but it is far too dangerous to let the protocol
* remove any files with path name substitution enabled.
* The protocol could accidentally hit the wrong file.
*/
if(!Config -> MiscConfig -> OverridePath)
{
if(DeleteFile(FileName))
{
LogAction(LocaleString(MSG_TERMXPR_LOGMSG_DELETE_FILE_TXT),FilePart(FileName));
return(0);
}
}
return(-1);
}
/* xpr_squery():
*
* Check how many characters are present in the serial buffer.
*/
LONG __saveds __asm
xpr_squery()
{
if(WriteRequest)
{
WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
DoIO(WriteRequest);
/* Return error if carrier is lost. */
if((WriteRequest -> io_Status & CIAF_COMCD) && Config -> SerialConfig -> CheckCarrier)
{
if(!CarrierMessage)
{
CarrierMessage = TRUE;
AddTransferInfo(LocaleString(MSG_TERMXPR_CARRIER_LOST_TXT));
}
Online = FALSE;
TransferError = TRUE;
}
else
return((LONG)WriteRequest -> IOSer . io_Actual);
}
return(-1);
}
/* xpr_getptr(LONG InfoType):
*
* Return a pointer to the term custom screen.
*/
LONG __saveds __asm
xpr_getptr(register __d0 LONG InfoType)
{
if(InfoType == 1)
return((LONG)Window -> WScreen);
else
return(-1);
}
/* xpr_stealopts(STRPTR Prompt,STRPTR Buffer):
*
* Steal the contents of the options buffer (replacement
* for xpr_gets).
*/
LONG __saveds __asm
xpr_stealopts(register __a0 STRPTR Prompt,register __a1 STRPTR Buffer)
{
if(Buffer)
strcpy(ProtocolOptsBuffer,Buffer);
return(1);
}